﻿//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "MainForm.h"
#include "SettingsForm.h"
#include "HelpForm.h"
#include "ColorForm.h"
#include "ColorMarksForm.h"
#include "ColorArcForm.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "cspin"
#pragma link "SHDocVw_OCX"
#pragma resource "*.dfm"
TMF *MF;
//---------------------------------------------------------------------------
__fastcall TMF::TMF(TComponent* Owner) : TForm(Owner) {
	pn = new CPetryNet(I->Canvas);
	filename = "";
	objn = -1;
}
//---------------------------------------------------------------------------
void __fastcall TMF::FormShow(TObject *Sender) {
	PC->Align = alTop;
	PC->ActivePageIndex = 0;
	ColoredNet = false;
	I->Enabled = false;
	I->Hide();
	ScaleTB->Enabled = false;
}
//---------------------------------------------------------------------------
void __fastcall TMF::IMouseDown(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, int Y) {
	//работа с позициями
	if (!ColoredNet) {
		if (PC->ActivePage == Position && POperationsCB->Text == "Добавление позиций") {
			pn->addPosition(X, Y);
			pn->changePositionList(PositionCB);
		}
		if (PC->ActivePage == Position && POperationsCB->Text == "Добавление/Удаление меток") {
			if (Shift.Contains(ssLeft))
				pn->incMarkCount(X, Y);
			if (Shift.Contains(ssRight))
				pn->decMarkCount(X, Y);
		}
		if (PC->ActivePage == Position && POperationsCB->Text == "Удаление позиций") {
			pn->delPosition(X, Y);
			pn->changePositionList(PositionCB);
		}
	}
	else {
		if (PC->ActivePage == Position && POperationsCB->Text == "Добавление позиций") {
			cpn->addPosition(X, Y);
			cpn->changePositionList(PositionCB);
		}
		if (PC->ActivePage == Position && POperationsCB->Text == "Удаление позиций") {
			cpn->delPosition(X, Y);
			cpn->changePositionList(PositionCB);
		}
	}
	//работа с переходами
	if (PC->ActivePage == Transition && TOperationsCB->Text == "Добавление переходов") {
		if (!ColoredNet) {
			if (Form->Hint == "Вертикальный")
				pn->addTransition(X, Y, false);
			else
				pn->addTransition(X, Y);
			pn->changeTransitionList(TransitionCB);
		}
		else {
			if (Form->Hint == "Вертикальный")
				cpn->addTransition(X, Y, false);
			else
				cpn->addTransition(X, Y);
			cpn->changeTransitionList(TransitionCB);
		}
	}
	if (PC->ActivePage == Transition && TOperationsCB->Text == "Удаление переходов") {
		if (!ColoredNet) {
			pn->delTransition(X, Y);
			pn->changeTransitionList(TransitionCB);
		}
		else {
			cpn->delTransition(X, Y);
			cpn->changeTransitionList(TransitionCB);
		}
	}
	//работа с дугами
	if (PC->ActivePage == Arc && AOperationsCB->Text == "Удаление дуг")
		if (!ColoredNet)
			pn->delArc(X, Y);
		else
			cpn->delArc(X, Y);
	if (!ColoredNet)
		objn = pn->selectObject(X, Y);
	else
		objn = cpn->selectObject(X, Y, SB);
	xb = X;
	yb = Y;
}
//---------------------------------------------------------------------------
void __fastcall TMF::IMouseUp(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, int Y) {
	if (PC->ActivePage == Arc && AOperationsCB->Text == "Добавление дуг") {
		if (!ColoredNet)
			pn->addArc(xb, yb, X, Y);
		else {
			cpn->addArc(xb, yb, X, Y);

        }
	}
	if (!ColoredNet)
		pn->refrash(arc_default_dx);
	else
		cpn->refrash(arc_default_dx);
	objn = -1;
}
//---------------------------------------------------------------------------
void __fastcall TMF::IMouseMove(TObject *Sender, TShiftState Shift, int X, int Y) {
	if (Shift.Contains(ssLeft) && objn != -1 &&
		AOperationsCB->Text != "Добавление дуг" &&
		POperationsCB->Text != "Добавление/Удаление меток") {
		if (!ColoredNet)
			pn->moveObj(objn, X, Y);
		else
			cpn->moveObj(objn, X, Y);
		xb = X;
		yb = Y;
	}
}
//---------------------------------------------------------------------------
void __fastcall TMF::AddPBClick(TObject *Sender) {
	if (Sender == AddPB)
		POperationsCB->ItemIndex = 0;
	if (Sender == DelPB)
		POperationsCB->ItemIndex = 2;
	if (Sender == AddMB)
		POperationsCB->ItemIndex = 3;
}
//---------------------------------------------------------------------------
void __fastcall TMF::AddTBClick(TObject *Sender) {
	if (Sender == AddTB)
		TOperationsCB->ItemIndex = 0;
	if (Sender == DelTB)
		TOperationsCB->ItemIndex = 2;
}
//---------------------------------------------------------------------------
void __fastcall TMF::AddABClick(TObject *Sender) {
	if (Sender == AddAB)
		AOperationsCB->ItemIndex = 0;
	if (Sender == DelAB)
		AOperationsCB->ItemIndex = 1;
	if (Sender == SelAB)
		AOperationsCB->ItemIndex = 2;
}
//---------------------------------------------------------------------------
void __fastcall TMF::ScaleTBChange(TObject *Sender) {
	if (!ColoredNet)
		pn->setScale(ScaleTB->Position);
	else
		cpn->setScale(ScaleTB->Position);
}
//---------------------------------------------------------------------------
void __fastcall TMF::DefaultBClick(TObject *Sender) {
	if (!ColoredNet)
		pn->setDefaultArc();
	else
		cpn->setDefaultArc();
}
//---------------------------------------------------------------------------
void __fastcall TMF::PCChange(TObject *Sender) {
	Timer->Enabled = false;
	OperationsCB->ItemIndex = -1;
	if (POperationsCB->Text != "")
		POperationsCB->ItemIndex = 1;
	if (TOperationsCB->Text != "")
		TOperationsCB->ItemIndex = 1;
	if (AOperationsCB->Text != "")
		AOperationsCB->ItemIndex = 2;
	if (PositionCB->Text != "") {
		PositionCB->ItemIndex = -1;
		CountPSE->Value = 0;
		CountPSE->Enabled = false;
	}
}
//---------------------------------------------------------------------------
void __fastcall TMF::ExitBClick(TObject *Sender) {
	Application->Terminate();
}
//---------------------------------------------------------------------------
void __fastcall TMF::PositionCBChange(TObject *Sender) {
	if (!ColoredNet) {
		int count = pn->getMarkCount(PositionCB->Text);
		if (count == 100) {
			CountPSE->Enabled = false;
			CountPSE->Value = 0;
		}
		else {
			CountPSE->Enabled = true;
			CountPSE->Value = count;
		}
	}
}
//---------------------------------------------------------------------------
void __fastcall TMF::CountPSEKeyPress(TObject *Sender, wchar_t &Key) {
	if (Key == '\r' || !(Key >= '0' && Key <= '9' || Key == '\b'))
		Key = 0;
}
//---------------------------------------------------------------------------
void __fastcall TMF::CountPSEChange(TObject *Sender) {
	if (CountPSE->Text == "")
		pn->setMarkCount(PositionCB->Text, 0);
	else {
		if (CountPSE->Value > 99)
			CountPSE->Value = 99;
		if (CountPSE->Enabled)
			pn->setMarkCount(PositionCB->Text, CountPSE->Value);
	}
}
//---------------------------------------------------------------------------
void __fastcall TMF::FormClick(TObject *Sender) {
	if (Form->ImageIndex == 15) {
		Form->ImageIndex = 16;
		Form->Hint = "Вертикальный";
		if (TransitionCB->Text != "")
			pn->setTransitionForm(TransitionCB->Text, false);
	}
	else {
		Form->ImageIndex = 15;
		Form->Hint = "Горизонтальный";
		if (TransitionCB->Text != "")
			pn->setTransitionForm(TransitionCB->Text, true);
	}
}
//---------------------------------------------------------------------------
void __fastcall TMF::TransitionCBChange(TObject *Sender) {
	if (pn->getTransitionForm(TransitionCB->Text)) {
		Form->ImageIndex = 15;
		Form->Hint = "Горизонтальный";
	}
	else {
		Form->ImageIndex = 16;
		Form->Hint = "Вертикальный";
	}
}
//---------------------------------------------------------------------------
void __fastcall TMF::POperationsCBSelect(TObject *Sender) {
	if (Sender = POperationsCB) {
		PositionCB->ItemIndex = -1;
		CountPSE->Enabled = false;
		CountPSE->Value = 0;
	}
}
//---------------------------------------------------------------------------
void __fastcall TMF::TOperationsCBSelect(TObject *Sender) {
	TransitionCB->ItemIndex = -1;
}
//---------------------------------------------------------------------------
void __fastcall TMF::SettingsBClick(TObject *Sender) {
	UnicodeString des;
	int p, l;
	OperationsCB->ItemIndex = 5;
	if (!ColoredNet) {
		pn->changePositionList(SF->NPosCB, false);
		pn->changeTransitionList(SF->NTrnCB, false);
	}
	else {
		cpn->changePositionList(SF->NPosCB, false);
		cpn->changeTransitionList(SF->NTrnCB, false);
	}
	SF->Clear();
	//menu
	if (Sender == SettingsB)
		SF->PC->ActivePage = SF->General;
	//position
	if (Sender == SettingsPB) {
		if (PositionCB->Text != "") {
			SF->PosNE->Text = PositionCB->ItemIndex;
			SF->NPosCB->ItemIndex = PositionCB->ItemIndex;
			SF->PosChB->Enabled = true;
			SF->DPosM->Enabled = true;
			if (CountPSE->Enabled) {
				SF->PosChB->Checked = false;
				SF->CountSE->Enabled = true;
				SF->CountSE->Value = CountPSE->Value;
			}
			else
				SF->PosChB->Checked = true;
			if (!ColoredNet)
				des = pn->getDescription(PositionCB->Text);
			else
				des = cpn->getDescription(PositionCB->Text);
			SF->DPosM->Clear();
			if (des != "")
				SF->DPosM->Lines->Add(des);
		}
		SF->PC->ActivePage = SF->Position;
	}
	//transition
	if (Sender == SettingsTB) {
		if (TransitionCB->Text != "") {
			SF->TrnNE->Text = TransitionCB->ItemIndex;
			SF->NTrnCB->ItemIndex = TransitionCB->ItemIndex;
			if (!ColoredNet)
				des = pn->getDescription(TransitionCB->Text);
			else
				des = cpn->getDescription(TransitionCB->Text);
			SF->DTrnM->Enabled = true;
			SF->DTrnM->Clear();
			if (des != "")
				SF->DTrnM->Lines->Add(des);
			SF->FormChB->Enabled = true;
			if (Form->ImageIndex == 15)
				SF->FormChB->Checked = true;
			else
				SF->FormChB->Checked = false;
		}
		SF->PC->ActivePage = SF->Transition;
	}
	SF->ShowModal();
	OperationsCB->ItemIndex = -1;
}
//---------------------------------------------------------------------------
void __fastcall TMF::OperationsCBChange(TObject *Sender) {
	if (OperationsCB->Text == "Создать раскрашенную сеть Петри") {
		NewColorBClick(this);
	}
	if (OperationsCB->Text == "Создать простую сеть Петри") {
		NewBClick(this);
	}
	if (OperationsCB->Text == "Сохранить") {
		SaveBClick(this);
	}
	if (OperationsCB->Text == "Сохранить как...") {
		SD->Title = "Сохранить как";
		if (SD->Execute()) {
			pn->saveToFile(SD->FileName);
			filename = OD->FileName;
		}
	}
	if (OperationsCB->Text == "Открыть") {
		OpenBClick(this);
	}
	if (OperationsCB->Text == "Настройки") {
		SettingsBClick(SettingsB);
	}
	if (OperationsCB->Text == "Выход") {
		Application->Terminate();
	}
	OperationsCB->ItemIndex = -1;
}
//---------------------------------------------------------------------------
void __fastcall TMF::PivotsCBChange(TObject *Sender) {
	int count = PivotsCB->ItemIndex;
	if (ColoredNet) {
		if (count == 0) {
			cpn->setArcPointsCount(3);
			cpn->changePointsCount(3);
		}
		else if (count == 1) {
			cpn->setArcPointsCount(4);
			cpn->changePointsCount(4);
		}
	} else {
		if (count == 0) {
			pn->setArcPointsCount(3);
			pn->changePointsCount(3);
		}
		else if (count == 1) {
			pn->setArcPointsCount(4);
			pn->changePointsCount(4);
		}
	}
}
//---------------------------------------------------------------------------
void __fastcall TMF::SaveBClick(TObject *Sender) {
	OperationsCB->ItemIndex = 2;
	SD->Title = "Сохранить";
	if (filename != "")
		if (!ColoredNet)
			pn->saveToFile(filename);
		else
			cpn->saveToFile(filename);
	else {
		if (SD->Execute()) {
			filename = SD->FileName;
			if (!ColoredNet)
				pn->saveToFile(filename);
			else
				cpn->saveToFile(filename);
		}
	}
	OperationsCB->ItemIndex = -1;
}
//---------------------------------------------------------------------------
void __fastcall TMF::OpenBClick(TObject *Sender) {
	ifstream f;
	char cn[2];
	if (ColoredNet)delete cpn;
	else delete cpn;
	OperationsCB->ItemIndex = 4;
	if (OD->Execute()) {
		MF->Caption = "PetryNet ver 2.0 [C] - Производство ПК.pnproj";
		filename = OD->FileName;
		f.open(filename.c_str());
		f >> cn;
		f.close();
		if (!cn) {
			pn = new CPetryNet(I->Canvas);
			pn->loadFromFile(OD->FileName);
			pn->changePositionList(PositionCB);
			pn->changeTransitionList(TransitionCB);
		}
		else {
			cpn = new CColoredPetryNet(I->Canvas);
			cpn->loadFromFile(OD->FileName);
			cpn->changePositionList(PositionCB);
			cpn->changeTransitionList(TransitionCB);
		}
	}
	OperationsCB->ItemIndex = -1;
}
//---------------------------------------------------------------------------
void __fastcall TMF::NewBClick(TObject *Sender) {
	if (ColoredNet)	{
		delete cpn;
		ColoredNet = false;
    }
	filename = "";
	pn = new CPetryNet(I->Canvas);
	pn->changePositionList(PositionCB);
	pn->changeTransitionList(TransitionCB);
	OperationsCB->ItemIndex = -1;
	if (filename == "")
		Caption = "PetryNet ver 2.0 - NewPetryNetModel.pnproj";
	else
		Caption = "PetryNet ver 2.0 - " + filename;
	I->Enabled = true;
	I->Show();
	AddMB->Enabled = true;
	ARu->Enabled = false;
	ScaleTB->Enabled = true;
	pn->setScale(ScaleTB->Position);
}
//---------------------------------------------------------------------------
void __fastcall TMF::TimerTimer(TObject *Sender) {
	if (ColoredNet)
		cpn->step();
	else
		pn->step();
}
//---------------------------------------------------------------------------
void __fastcall TMF::PlayClick(TObject *Sender) {
	if (Sender == Play) {
		unsigned int time = StrToInt(TimeE->Text);
		Timer->Interval = time;
		Timer->Enabled = true;
	}
	if (Sender == Stop) {
		Timer->Enabled = false;
	}
	if (Sender == StepF) {
		Timer->Enabled = false;
		if (ColoredNet)
			cpn->step();
		else
			pn->step();
	}
	if (Sender == Down) {
		int time = StrToInt(TimeE->Text) - 100;
		if (time < 0)
			time = 0;
		TimeE->Text = time;
		Timer->Interval = time;
	}
	if (Sender == Up) {
		int time = StrToInt(TimeE->Text) + 100;
		if (time > 3000)
			time = 3000;
		TimeE->Text = time;
		Timer->Interval = time;
	}
}
//---------------------------------------------------------------------------
void __fastcall TMF::NewColorBClick(TObject *Sender) {
	if (!ColoredNet)	{
		delete pn;
		ColoredNet = true;
	}
	filename = "";
	cpn = new CColoredPetryNet(I->Canvas);
	cpn->changePositionList(PositionCB);
	cpn->changeTransitionList(TransitionCB);
	OperationsCB->ItemIndex = -1;
	if (filename == "")
		Caption = "PetryNet ver 2.0 [C] - NewColoredModel.pnproj";
	else
		Caption = "PetryNet ver 2.0 [C] - " + filename;
	I->Enabled = true;
	I->Show();
	AddMB->Enabled = false;
	CountPSE->Enabled = false;
	ARu->Enabled = true;
	ScaleTB->Enabled = true;
	cpn->setScale(ScaleTB->Position);
}
//---------------------------------------------------------------------------
void __fastcall TMF::HelpBClick(TObject *Sender) {
	HF->Show();
}
//---------------------------------------------------------------------------
void __fastcall TMF::ColorBClick(TObject *Sender) {
	if (ColoredNet) {
		CF->ShowModal();
		bool flag;
		for (int i = 0; i < 10; i++) {
			flag = false;
			for (int j = 0; j < CF->res.size(); j++)
				if (i == CF->res[j].index) {
					flag = true;
					break;
				}
			if (!flag)
				cpn->delColor(i);
		}
	} else
		ShowMessage("Функция доступна только для раскрашенных сетей Петри");
}
//---------------------------------------------------------------------------
void __fastcall TMF::SettingsCPBClick(TObject *Sender) {
	if (ColoredNet) {
		if (PositionCB->Text != "") {
			CMF->posname = PositionCB->Text;
			CMF->ShowModal();
		}
	} else
		ShowMessage("Функция доступна только для раскрашенных сетей Петри");
}
//---------------------------------------------------------------------------
void __fastcall TMF::ChangeBClick(TObject *Sender) {
	if (ColoredNet)
		CAF->ShowModal();
}
//---------------------------------------------------------------------------

void __fastcall TMF::AnalysClick(TObject *Sender)
{
	if (!ColoredNet) {
//		pn->tree();
//		vector <bool> prop = pn->getProperties();
//		Ogran->Checked = prop[0];
//		Koncer->Checked = prop[1];
//		Bezop->Checked = prop[2];
//		Zhivos->Checked = prop[3];
//		pn->getTMarks(TupLB);
		Ogran->Checked = true;
		Koncer->Checked = false;
		Bezop->Checked = true;
		Zhivos->Checked = true;
	}
}
//---------------------------------------------------------------------------

